// 统一的HTTP客户端（基于fetch），封装常用请求逻辑与错误处理
import { API_BASE_URL } from '../constants/config';

// 开发环境日志开关（优先使用 Vite 的 import.meta.env.DEV），支持显式开启 VITE_DEBUG_HTTP
const isDev = (typeof import.meta !== 'undefined' && import.meta?.env?.DEV) || (typeof process !== 'undefined' && process?.env?.NODE_ENV !== 'production');
const debugHttp = (typeof import.meta !== 'undefined' && import.meta?.env?.VITE_DEBUG_HTTP) || (typeof process !== 'undefined' && process?.env?.VITE_DEBUG_HTTP);
const shouldLog = isDev || String(debugHttp).toLowerCase() === 'true';
console.log('[HTTP] Debug Mode:', shouldLog);
const log = (...args) => {
  console.log(...args);
};

const defaultHeaders = {
  'Content-Type': 'application/json',
};

function getAuthToken() {
  try {
    const raw = localStorage.getItem('nexusgo.auth');
    if (!raw) return null;
    const parsed = JSON.parse(raw);
    return parsed?.token || null;
  } catch {
    return null;
  }
}

// 获取完整URL
const buildUrl = (path) => {
  if (!path) return API_BASE_URL;
  if (path.startsWith('http')) return path;
  // 确保以单斜杠拼接
  const base = API_BASE_URL.endsWith('/') ? API_BASE_URL.slice(0, -1) : API_BASE_URL;
  const p = path.startsWith('/') ? path : `/${path}`;
  return `${base}${p}`;
};

// 统一请求方法
export async function request(method, path, { headers = {}, params, body, signal } = {}) {
  const url = new URL(buildUrl(path), window.location.origin);

  // 附加查询参数
  if (params && typeof params === 'object') {
    Object.entries(params).forEach(([k, v]) => {
      if (v !== undefined && v !== null) url.searchParams.set(k, String(v));
    });
  }

  const opts = {
    method: method.toUpperCase(),
    headers: { ...defaultHeaders, ...headers },
    signal,
    credentials: 'include',
  };

  // 注入认证Token（如存在）
  const token = getAuthToken();
  if (token) {
    opts.headers['Authorization'] = `Bearer ${token}`;
  }

  const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;
  if (isFormData) {
    const cloned = { ...opts.headers };
    delete cloned['Content-Type'];
    opts.headers = cloned;
    opts.body = body;
  } else if (body !== undefined) {
    opts.body = typeof body === 'string' ? body : JSON.stringify(body);
  }

  // 请求前日志
  log('[HTTP] Request', {
    method: opts.method,
    url: url.toString(),
    headers: opts.headers,
    params,
    body,
  });

  let res;
  try {
    res = await fetch(url.toString(), opts);
  } catch (networkErr) {
    // 网络层错误（如断网、跨域被拦截等）
    // eslint-disable-next-line no-console
    console.error('[HTTP] Network Error', {
      method: opts.method,
      url: url.toString(),
      error: networkErr?.message || networkErr,
    });
    throw networkErr;
  }

  const contentType = res.headers.get('content-type') || '';
  const isJson = contentType.includes('application/json');
  const payload = isJson ? await res.json() : await res.text();

  if (!res.ok) {
    const err = new Error((isJson && payload && payload.message) || 'Request failed');
    err.status = res.status;
    err.data = payload;
    console.error('[HTTP] Response Error', {
      method: opts.method,
      url: url.toString(),
      status: res.status,
      data: payload,
    });
    throw err;
  }

  // 业务码判断：后端约定 code===200 为成功
  if (isJson && payload && typeof payload === 'object' && Object.prototype.hasOwnProperty.call(payload, 'code')) {
    if (payload.code !== 200) {
      const err = new Error(payload.message || 'Request failed');
      err.status = res.status;
      err.code = payload.code;
      err.data = payload.data;
      console.error('[HTTP] Response Error (Business)', {
        method: opts.method,
        url: url.toString(),
        status: res.status,
        code: payload.code,
        message: payload.message,
        data: payload.data,
      });
      throw err;
    }
    // 成功时，优先返回 data 字段，否则返回原始对象
    const unwrapped = Object.prototype.hasOwnProperty.call(payload, 'data') ? payload.data : payload;
    log('[HTTP] Response', {
      method: opts.method,
      url: url.toString(),
      status: res.status,
      data: unwrapped,
    });
    return unwrapped;
  }

  // 非 JSON 或不包含 code 字段，直接返回解析结果
  log('[HTTP] Response', {
    method: opts.method,
    url: url.toString(),
    status: res.status,
    data: payload,
  });
  return payload;
}

export const http = {
  get: (path, options) => request('GET', path, options),
  post: (path, options) => request('POST', path, options),
  put: (path, options) => request('PUT', path, options),
  patch: (path, options) => request('PATCH', path, options),
  delete: (path, options) => request('DELETE', path, options),
};
